package com.simple.utils;

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;

import java.text.*;
import java.util.*;

/**
 * @ClassName TimeUtil
 * @Author SimpleTree
 **/
@Slf4j
public class TimeUtil {
    private static String yyyyMMdd1 = "yyyy-MM-dd";
    private static String yyyyMMdd2 = "yyyy-MM-dd HH:mm:ss";
    private static String yyyyMMdd3 = "yyyy/MM/dd HH:mm:ss";

    public static String format(Date date) {
        return date == null ? "" : DateUtil.format(date, yyyyMMdd2);
    }

    public static String format(Date date, Integer type) {
        String regex = type == 1 ? yyyyMMdd1 : (type == 2 ? yyyyMMdd2 : yyyyMMdd3);
        return date == null ? "" : DateUtil.format(date, regex);
    }

    public static Date parse(String dateStr) {
        SimpleDateFormat sf = new SimpleDateFormat(yyyyMMdd2);
        try {
            return sf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Date parse(String dateStr, Integer type) {
        SimpleDateFormat sf = new SimpleDateFormat(type == 1 ? yyyyMMdd1 : (type == 2 ? yyyyMMdd2 : yyyyMMdd3));
        try {
            return sf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 获取当前系统时间
     *
     * @return String: yyyy-MM-dd HH:mm:ss
     */
    public static String getCurrentTimestamp() {
        return DateUtil.date().toString();
    }

    /**
     * 获取当前系统格式化日期
     *
     * @return String: yyyyMMdd 20191219
     */
    public static String getCurrentDateToStr() {
        return DateUtil.format(new Date(), "yyyyMMdd");
    }

    /**
     * 获取格式化日期
     *
     * @return String: yyyyMMdd 20191219
     */
    public static String getCurrentDateToStr(Date date) {
        return DateUtil.format(date, "yyyyMMdd");
    }

    /**
     * 获取当前系统格式化日期
     *
     * @return Integer: yyyyMMdd 20191219
     */
    public static Integer getCurrentDateToInt() {
        return Integer.parseInt(getCurrentDateToStr());
    }

    /**
     * 获取格式化日期
     *
     * @return Integer: yyyyMMdd 20191219
     */
    public static Integer getCurrentDateToInt(Date date) {
        return Integer.parseInt(getCurrentDateToStr(date));
    }

    /**
     * 将字符串转换为Date
     *
     * @param timestamp 字符串 如 yyyy-MM-dd HH-mm-ss 格式
     * @return Date
     */
    public static Date getDateTime(String timestamp) {
        return DateUtil.parse(timestamp);
    }

    /**
     * 可生成文件名称
     *
     * @return 1576727765434
     */
    public static String getTimeMill() {
        return String.valueOf(System.currentTimeMillis());
    }

    /**
     * 可生成文件名称
     *
     * @return 20191219115741041
     */
    public static String getTimeStamp() {
        return DateUtil.format(new Date(), "yyyyMMddHHmmssSSS");
    }


    /**
     * 时间差
     *
     * @param date1 被减数
     * @param date2 减数
     * @return 返回 单位 分钟
     */
    public static double dateDiffToHour(Date date1, Date date2) {
        double hour;
        long start = date1.getTime();
        long end = date2.getTime();
        long diff = end - start;
        hour = ((double) diff / (60 * 60 * 1000));
        // 保留小数
        NumberFormat nf = new DecimalFormat("0.0");
        hour = Double.parseDouble(nf.format(hour));
        return hour;
    }

    /**
     * 比较两个的时间大小 只比较时间  不比较日期
     * 小于 则 返回true
     *
     * @param date1 date1
     * @param date2 date2
     * @return boolean
     */
    public static int onlyCompareToTime(Date date1, Date date2) {
        int t1 = Integer.parseInt(DateUtil.format(date1, "HHmmssSS"));
        int t2 = Integer.parseInt(DateUtil.format(date2, "HHmmssSS"));
        return t1 - t2;
    }

    /**
     * 改变时间
     *
     * @param date 保留时间
     * @param c    保留日期
     * @return c的日期 + date的时间
     */
    public static Date changeDate(Date date, Date c) {
        String prefix = DateUtil.format(c, "yyyy-MM-dd");
        String blank = " ";
        String time = DateUtil.format(date, "HH:mm:ss");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date res = null;
        try {
            res = sdf.parse(prefix + blank + time);
        } catch (ParseException e) {
        }
        return res;
    }


    /**
     * 获取两个时间之间的月份
     *
     * @param planStartTime
     * @param planEndTime
     * @return
     */
    public static List<String> getBetweenTwoMonth(Date planStartTime, Date planEndTime) {
        ArrayList<String> result = new ArrayList<String>();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");

        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();

        min.setTime(planStartTime);
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

        max.setTime(planEndTime);
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

        Calendar curr = min;
        while (curr.before(max)) {
            //result.add(sdf.format(curr.getTime()));
            result.add(DateUtil.format(curr.getTime(), "M"));
            curr.add(Calendar.MONTH, 1);
        }
        return result;
    }

    /**
     * 返回日期之间
     *
     * @param date1
     * @param date2
     * @return
     */
    public static List<String> getBetweenDay(Date date1, Date date2) {
        List<String> days = new ArrayList<String>();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date1);

        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(date2);
        while (calendar1.getTime().getTime() <= date2.getTime()) {
            String dateFormates = dateFormat.format(calendar1.getTime());
            days.add(dateFormates);
            calendar1.set(Calendar.DAY_OF_YEAR, calendar1.get(Calendar.DAY_OF_YEAR) + 1);
        }
        return days;
    }


    /**
     * 获取当前月份下的一年前月份
     *
     * @param date
     * @return
     */
    public static List<String> getPassYearByNow(Date date) {
        List<String> list = new ArrayList<>();
        int currentMonth = DateUtil.month(date) + 1;
        int mid = currentMonth + 12;
        for (int i = 0; i < 12; i++) {
            if (i < currentMonth) {
                list.add(mid - 12 - i + "");
            } else {
                list.add(currentMonth + 12 - i + "");
            }
        }
        Collections.reverse(list);
        return list;
    }

    /**
     * 判断两个时间是否是同一天
     *
     * @param date1
     * @param date2
     * @return
     */
    public static String isSameDay(Date date1, Date date2) {
        String date1Str = DateUtil.format(date1, "yyyyMMdd");
        String date2Str = DateUtil.format(date2, "yyyyMMdd");
        if (date1Str.equals(date2Str)) {
            return " " + DateUtil.format(date2, "HH:mm:ss");
        }
        return " 00:00:00";
    }

    /**
     * 获取本月第一天
     *
     * @return
     */
    public static Date getFirstDayOfMonth() {
        int month = DateUtil.month(new Date());
        Calendar calendar = Calendar.getInstance();
        // 设置月份
        calendar.set(Calendar.MONTH, month);
        // 获取某月最小天数
        int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
        return getDayOfMonth(calendar, firstDay,1);
    }

    /**
     * 获取本月最后一天
     *
     * @return
     */
    public static Date getLastDayOfMonth() {
        int month = DateUtil.month(new Date());
        Calendar calendar = Calendar.getInstance();
        // 设置月份
        calendar.set(Calendar.MONTH, month);
        // 获取某月最大天数
        int lastDay = 0;
        //2月的平年瑞年天数
        if (month == 2) {
            lastDay = calendar.getLeastMaximum(Calendar.DAY_OF_MONTH);
        } else {
            lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        return getDayOfMonth(calendar, lastDay,2);
    }

    public static Date getDayOfMonth(Calendar calendar, Integer day,Integer type) {
        // 设置日历中月份的最大天数
        calendar.set(Calendar.DAY_OF_MONTH, day);
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateTime = sdf.format(calendar.getTime());
        String lastDayStr = type == 1 ? dateTime + " 00:00:00" : dateTime + " 23:59:59";
        Date time = null;
        try {
            time = parse(lastDayStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return time;
    }

    public static Integer getMonth(Date date) {
        return DateUtil.month(date) + 1;
    }

    public static void main(String[] args) {
        System.out.println(format(getFirstDayOfMonth()));
        System.out.println(format(getLastDayOfMonth()));
        System.out.println(getMonth(new Date()));
    }
}
